/* 
 * File:   World2D.cpp
 * Author: aljosa
 * 
 * Created on May 25, 2010, 8:54 PM
 */

#include "World2D.h"
#include "messages.h"
#include "RenderingSystem.h"
#include "Box2DNode.h"

namespace xEngine
{
    namespace CoreSystem
    {
        //
        // Constructor, destructor
        //
        World2D::World2D() : worldBox2D(NULL) {
        }

        World2D::~World2D() {
        }


        //
        // World creation, shutdown
        //
        bool World2D::create(float gravityX, float gravityY, float width, float height) {
            // Set world bounding box
            box.lowerBound = b2Vec2( SCREEN_TO_WORLD(this->position.x) - SCREEN_TO_WORLD(width/2), SCREEN_TO_WORLD(this->position.y) - SCREEN_TO_WORLD(height/2) );
            box.upperBound = b2Vec2( SCREEN_TO_WORLD(this->position.x) + SCREEN_TO_WORLD(width/2), SCREEN_TO_WORLD(this->position.y) + SCREEN_TO_WORLD(height/2) );

            // Create B2D world
            this->worldBox2D = new b2World(box,b2Vec2(gravityX, gravityY), true); // Create new Box2D world

            Messages::initMessage("World create", true);

            return true;
        }

        void World2D::shutDown() {
            // Clean predcessor's stuff
            World::shutDown();
            
            // Box2D
            if ( this->worldBox2D != NULL ) { // There is an Box2D world
                // TODO, BOX2D CLEANING STUFF

                // At last ...
                delete this->worldBox2D;
            }

            Messages::initMessage("World shutdown", true);

        }


        //
        // Nodes manipulation
        //
     /*   void World2D::addChild(Node *node) {

            // Add to tree, call node's addChild func
            Node::addChild(node);

        }

        void World2D::addSibling(Node *node) {

            // Add to tree, call node's addSibling func
            Node::addSibling(node);
        }*/


        /**
         * Draw method
         *
         * Virtual
         * Draws this object and takes care that draw calls are called recursively over the tree
         *
         */
        void World2D::draw(double deltaTime) {
            gluLookAt(0.0f, 0.0f, -30.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
        //    glTranslatef(0.0f, 0.0f, -1.0f);
            // Draw this node
            // ...

           // xEngine::Renderer::RenderingSystem::get()->setColor(RED);
        //    xEngine::Renderer::RenderingSystem::get()->drawCircle(Vector3(0.0f, 0.0f, -20.0f), 2, 5 );
          //  xEngine::Renderer::RenderingSystem::get()->Box2DRender.DrawAABB(&(this->box), b2Color(0.0f, 1.0f, 0.0f));

            // Draw children
            xEngine::PlatformIndependent::SceneNode::draw(deltaTime);
        }

        /**
         * Update method
         *
         * Virtual
         * Updates this object and takes care that update calls are called recursively over the tree
         *
         *
         */
        void World2D::update(double deltaTime) {
            // Update this node
            // ...

            // Box2D step func params
            float32 timeStep = 1.0f / 60.0f;
            int32 velocityIterations = 10; //6;
            int32 positionIterations = 10; //2;


            
            // Box2D step
            this->worldBox2D->Step(deltaTime, velocityIterations, positionIterations);

            // Update children
            // No need ?
           /* if (this->child) {
                ((SceneNode*)this->child)->update();
            }*/
        }

        /**
         * Animate method
         *
         * Virtual
         * Animates this object and takes care that animate calls are called recursively over the tree
         *
         */
        void World2D::animate(double deltaTime) {
            // Animate this node
            // ...

            // Animate children
                // Update children
            if (this->child) {
                ((SceneNode*)this->child)->animate(deltaTime);
            }

        }
    }
}

